package utils

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"
)

// 结构体转map
func StructToMap(obj interface{}) map[string]interface{} {
	objValue := reflect.ValueOf(obj)
	objType := objValue.Type()

	data := make(map[string]interface{})
	for i := 0; i < objValue.NumField(); i++ {
		field := objType.Field(i)
		value := objValue.Field(i).Interface()

		data[strings.ToLower(field.Name)] = value
	}

	return data
}

// 结构体转map(字段所有值转为string，若是结构体转为json字符串)
func StructToStringMap(obj interface{}) map[string]string {
	objValue := reflect.ValueOf(obj)
	return handleMap(objValue)
}

// 结构体转map，优先使用form标签字段
func StructToFormMap(obj interface{}) map[string]string {
	objValue := reflect.ValueOf(obj)
	objType := objValue.Type()

	data := make(map[string]string)
	for i := 0; i < objValue.NumField(); i++ {
		fieldType := objType.Field(i)
		fieldValue := objValue.Field(i)
		// 获取form标签字段
		fieldName := fieldType.Tag.Get("form")
		if fieldName == "" {
			fieldName = fieldType.Name
		}
		if fieldType.PkgPath == "" {
			if fieldType.Type.Kind() == reflect.Struct {
				structMap := handleMap(fieldValue)
				data[strings.ToLower(fieldName)] = MapToJson(structMap)
			} else if fieldType.Type.Kind() == reflect.Slice || fieldType.Type.Kind() == reflect.Array {
				var valueArray []string
				for i := 0; i < fieldValue.Len(); i++ {
					// 获取数组元素的值
					arrayValue := fieldValue.Index(i)
					structMap := handleMap(arrayValue)
					valueArray = append(valueArray, MapToJson(structMap))
				}
				jsonArray, _ := json.Marshal(valueArray)
				data[strings.ToLower(fieldName)] = string(jsonArray)
			} else {
				// 根据字段类型转换值
				switch value := fieldValue.Interface().(type) {
				case string:
					data[strings.ToLower(fieldName)] = value
				case int:
					data[strings.ToLower(fieldName)] = fmt.Sprintf("%d", value)
				}
			}
		}
	}
	return data
}

// 结构体中包含的结构体处理
func handleMap(objValue reflect.Value) map[string]string {
	data := make(map[string]string)
	objType := objValue.Type()
	for i := 0; i < objValue.NumField(); i++ {
		fieldType := objType.Field(i)
		fieldValue := objValue.Field(i)
		// 获取form标签字段
		fieldName := fieldType.Tag.Get("form")
		if fieldName == "" {
			fieldName = fieldType.Name
		}
		// 根据字段类型转换值
		switch value := fieldValue.Interface().(type) {
		case string:
			data[strings.ToLower(fieldName)] = value
		case int:
			data[strings.ToLower(fieldName)] = fmt.Sprintf("%d", value)
		}
	}
	return data
}

// map合并
func MergeMap(map1, map2 map[string]interface{}) map[string]interface{} {
	merged := make(map[string]interface{})

	// 将 map1 中的键值对添加到 merged 中
	for key, value := range map1 {
		merged[key] = value
	}

	// 将 map2 中的键值对添加到 merged 中，如果键已存在，则更新对应的值
	for key, value := range map2 {
		merged[key] = value
	}

	return merged
}

// map合并
func MergeStringMap(map1, map2 map[string]string) map[string]string {
	merged := make(map[string]string)

	// 将 map1 中的键值对添加到 merged 中
	for key, value := range map1 {
		merged[key] = value
	}

	// 将 map2 中的键值对添加到 merged 中，如果键已存在，则更新对应的值
	for key, value := range map2 {
		merged[key] = value
	}

	return merged
}

// 结构体转换
func MapStringToMap(stringMap map[string]string) map[string]interface{} {
	newMap := make(map[string]interface{})
	for key, value := range stringMap {
		newMap[key] = value
	}
	return newMap
}

// 结构体转为json字符串
func StructToJson(obj any) string {
	jsonString, err := json.Marshal(obj)
	if err != nil {
		return ""
	}
	return string(jsonString)
}

func MapToJson(obj any) string {
	jsonData, err := json.Marshal(obj)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	return string(jsonData)
}
